<?php
// +----------------------------------------------------------------------
// | Bwsaas
// +----------------------------------------------------------------------
// | Copyright (c) 2015~2020 http://www.buwangyun.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Gitee ( https://gitee.com/buwangyun/bwsaas )
// +----------------------------------------------------------------------
// | Author: buwangyun <hnlg666@163.com>
// +----------------------------------------------------------------------
// | Date: 2020-9-28 10:55:00
// +----------------------------------------------------------------------

namespace app\manage\controller\member;

use app\common\model\MemberMiniapp;
use app\common\model\WechatOpenToken;

use buwang\facade\WechatMp;
use buwang\facade\WechatProgram;
use buwang\base\MemberBaseController;

use think\facade\Request;
use Exception;

class WechatAuth extends MemberBaseController
{

    public function initialize()
    {
        parent::initialize();

    }

    /**
     * 以下部分是微信小程序官方操作
     * 发起授权
     * @param string $type
     * @return json
     */
    public function openAuth(string $type)
    {
        $this->isMemberAppAuth();
        //在此查询看看当前应用是公众号还是小程序
        if ($this->member_miniapp->is_lock == 1) {
            return $this->error_jump('当前应用已停止服务');
        }
        if (!$this->member_miniapp->miniapp->is_openapp) {
            return $this->error_jump('非开放平台应用不支持扫码授权,请手动配置');
        }
        //查询授权是否过期
        $appId = $type == 'official' ? $this->member_miniapp->mp_appid : $this->member_miniapp->miniapp_appid;
        if (!empty($appId)) {
            try {
                $assess = WechatOpenToken::accessToken($this->member_miniapp_id, $appId);
            } catch (Exception $e) {
                return $this->error_jump($e->getMessage());
            }
            if ($assess) {
                $url = $type == 'official' ? '/manage/member.setting/index' : '/manage/member.setting/index';//暂时一样
                return $this->error_jump('授权未过期,请15分钟后再试。', $url . $this->member_miniapp_id);
            }
        }
        try {
            $url = WechatMp::openConfig()->getPreAuthorizationUrl((string)url('/manage/member/openAuthCallback', ['miniapp_id' => $this->member_miniapp_id], false, true));
        } catch (Exception $e) {
            return $this->error_jump($e->getMessage());
        }
        header("location:$url");
        exit;
    }

    /**
     * 微信开放平台推送车票(1次/10分钟)
     * 有了车票要保存下来,获取授权时要用
     * @return json
     */
    public function openAuthCallback()
    {
        $this->isMemberAppAuth();
        //在此查询看看当前应用是公众号还是小程序
        if ($this->member_miniapp->is_lock == 1) {
            return $this->error_jump('当前应用已停止服务',NOT_JUMP);
        }
        if (!$this->member_miniapp->miniapp->is_openapp) {
            return $this->error_jump('应用不支持扫码授权,请手动配置', '/manage/member.setting/index', ['miniapp_id' => $this->member_miniapp_id]);
        }
        if (Request::get('state/s') == 'STATE') {
            return $this->error_jump('您禁止了微信授权,所以暂时无权创建应用', '/manage/member.setting/index', ['miniapp_id' => $this->member_miniapp_id]);
        }
        $openPlatform = WechatMp::openConfig();
        if (empty($openPlatform)) {
            return $this->error_jump('应用未配置开放平台授权信息',NOT_JUMP);
        }
        try {
            $appinfo = $openPlatform->handleAuthorize();
        } catch (Exception $e) {
            return $this->error_jump($e->getMessage());
        }
        if (!empty($appinfo['errcode'])) {
            return $this->error_jump($appinfo['errmsg']);
        }
        $appid = $appinfo['authorization_info']['authorizer_appid'];
        //根据凭证获取的应用信息
        $miniProgram = $openPlatform->getAuthorizer($appid);
        if (empty($miniProgram['authorizer_info'])) {
            return $this->error_jump('授权信息读取失败',NOT_JUMP);
        }
        $head_img = $miniProgram['authorizer_info']['head_img'] ?? '';
        //授权方为公众号
        if (empty($miniProgram['authorizer_info']['MiniProgramInfo'])) {
            if ($miniProgram['authorizer_info']['service_type_info']['id'] != 2) {
                return $this->error_jump('不支持订阅号',NOT_JUMP);
            }
            if ($miniProgram['authorizer_info']['verify_type_info']['id'] < 0) {
                return $this->error_jump('未通过微信认证的服务号禁止接入',NOT_JUMP);
            }
            $app_data['mp_appid'] = $appid;  //公众号
            $app_data['mp_head_img'] = $head_img;
            $app_data['mp_qrcode_url'] = $miniProgram['authorizer_info']['qrcode_url'];
            $app_data['mp_open_auth'] = 1;//标识公众号已经开放平台授权
        } else {//授权方为小程序
            if ($miniProgram['authorizer_info']['verify_type_info']['id'] < 0) {
                return $this->error_jump('未通过微信认证的小程序禁止接入',NOT_JUMP);
            }
            $app_data['miniapp_appid'] = $appid;  //小程序
            $app_data['miniapp_head_img'] = $head_img;
            $app_data['miniapp_qrcode_url'] = $miniProgram['authorizer_info']['qrcode_url'];
            $app_data['miniapp_open_auth'] = 1;//标识小程序已经开放平台授权
        }
        $app_data['is_open'] = 1;//标识已经开放平台授权
        MemberMiniapp::where(['id' => $this->member_miniapp_id])->update($app_data);
        //更新授权信息
        $at['member_miniapp_id'] = $this->member_miniapp_id;
        $at['appid'] = $appid;
        $at['access_token'] = $appinfo['authorization_info']['authorizer_access_token'];
        $at['expires_in'] = $appinfo['authorization_info']['expires_in'];
        $at['refresh_token'] = $appinfo['authorization_info']['authorizer_refresh_token'];
        WechatOpenToken::edit($at);//增加或者更新数据
        //设置授权域名
        if (!empty($miniProgram['authorizer_info']['MiniProgramInfo'])) {//授权方为小程序
            $url['action'] = 'set';
            $url['requestdomain'] = ['https://res.' . Request::rootDomain(), 'https://' . $this->request->host()];
            $url['wsrequestdomain'] = ['wss://res.' . Request::rootDomain(), 'https://' . $this->request->host()];
            $url['uploaddomain'] = $url['requestdomain'];
            $url['downloaddomain'] = $url['requestdomain'];
            $domain = WechatProgram::isTypes($this->member_miniapp_id)->domain;//设置服务器域名
            $domain->modify($url);
            $domain->setWebviewDomain([Request::scheme() . '://' . Request::rootDomain()]);    //设置业务域名
        }
        return $this->redirect('/manage/member.setting/index',['miniapp_id'=>$this->member_miniapp_id]);
    }
}